﻿//     Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Threading.Tasks;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Gateway.Console.Models;
using Gateway.Console.Services;
using Gateway.Console.Services.Azure;

namespace Gateway.Console.Controllers
{
    public class SecurityController : OAuthAccessController
    {
        public SecurityController()
            : base("Security", new[] { ResourceSelectors.RDFE, ResourceSelectors.GraphApi  })
        {

        }

        // GET: /Security/
        public async Task<ActionResult> Index()
        {
            return await DoWithAccessAsync("Index", null, async () =>
            {
                var model = await _db.SecurityModels.FirstOrDefaultAsync();
                if (model == null)
                {
                    model = new SecurityModel();
                }
                if (!ViewBag.GraphApiAuthorizationFailure && String.IsNullOrWhiteSpace(model.Directory))
                {
                    using (var graphApi = Session.GetGraphApi())
                    {
                        model.Directory = await graphApi.GetDefaultDomainNameAsync();
                        model.ApplicationName = String.Empty;
                    }
                }
                return View(model);
            });
        }

        // POST: /Security/Index
        [HttpPost]
        public async Task<ActionResult> Index(SecurityModel securitymodel)
        {
            if (ModelState.IsValid)
            {
                if (securitymodel.Id == 0)
                {
                    _db.SecurityModels.Add(securitymodel);
                }
                else
                {
                    _db.Entry(securitymodel).State = EntityState.Modified;
                }
                await _db.SaveChangesAsync();
                if (securitymodel.EnableAuthenticationValue)
                {
                    await UpdateApplicationAsync(securitymodel, true);
                }
                return RedirectToAction("Index");
            }

            return View(securitymodel);
        }

        // POST: /Security/EnableRdfeAccess
        [HttpPost]
        public async Task<ActionResult> EnableRdfeAccess(SecurityModel securitymodel)
        {
            return await DoWithAccessAsync("EnableRdfeAccess", null, async () =>
            {
                if (ViewBag.GraphApiAuthorizationFailure)
                {
                    return new HttpUnauthorizedResult();
                }
                using (var graphApi = Session.GetGraphApi())
                {
                    await graphApi.EnableRdfeAccessAsync();
                }
                Session.ResetOAuthInformation(ResourceSelectors.RDFE);
                Session.PermissionIsBeingProvisioned(ResourceSelectors.RDFE);
                return RedirectToAction("Index");
            });
        }

        public async Task<ActionResult> Edit(int? id)
        {
            return await DoWithAccessAsync("Edit", null, async () =>
            {
                if (id == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                SecurityModel securitymodel = await _db.SecurityModels.FindAsync(id);
                if (securitymodel == null)
                {
                    return HttpNotFound();
                }
                return View(securitymodel);
            });
        }

        // POST: /Security/Edit/
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Edit([Bind(Include = "Id,Directory,ApplicationName")] SecurityModel securitymodel)
        {
            if (ModelState.IsValid)
            {
                var currentModel = await _db.SecurityModels.FindAsync(securitymodel.Id);
                if (currentModel != null)
                {
                    currentModel.Directory = securitymodel.Directory;
                    currentModel.ApplicationName = securitymodel.ApplicationName;
                    if (currentModel.EnableAuthenticationValue)
                    {
                        await UpdateApplicationAsync(currentModel, false);
                    }
                    _db.Entry(currentModel).State = EntityState.Modified;
                    await _db.SaveChangesAsync();
                }
                return RedirectToAction("Index");
            }
            return View(securitymodel);
        }

        private async Task UpdateApplicationAsync(SecurityModel model, bool saveChanges)
        {
            // See if we need to create a WAAD Application for a deployment that is already running
            bool updateModel = false;
            var deployment = await _db.Deployments.FirstOrDefaultAsync();
            if (deployment != null && !String.IsNullOrWhiteSpace(deployment.ServiceUrl))
            {
                using (var graphApi = Session.GetGraphApi())
                {
                    if (String.IsNullOrWhiteSpace(model.ApplicationName))
                    {
                        model.ApplicationName = deployment.ServiceUrl;
                        updateModel = true;
                    }
                    await graphApi.EnableWebSSOAsync(model.ApplicationName, model.MultiTenantAuthenticationValue, deployment.ServiceUrl);
                }
            }
            if (saveChanges && updateModel)
            {
                _db.Entry(model).State = EntityState.Modified;
                await _db.SaveChangesAsync();
            }
        }
    }
}
